home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-9.10-netbook-remix-PL.iso / casper / filesystem.squashfs / usr / share / perl5 / HTTP / Message.pm < prev    next >
Text File  |  2009-08-13  |  30KB  |  1,109 lines

  1. package HTTP::Message;
  2.  
  3. use strict;
  4. use vars qw($VERSION $AUTOLOAD);
  5. $VERSION = "5.831";
  6.  
  7. require HTTP::Headers;
  8. require Carp;
  9.  
  10. my $CRLF = "\015\012";   # "\r\n" is not portable
  11. $HTTP::URI_CLASS ||= $ENV{PERL_HTTP_URI_CLASS} || "URI";
  12. eval "require $HTTP::URI_CLASS"; die $@ if $@;
  13.  
  14. *_utf8_downgrade = defined(&utf8::downgrade) ?
  15.     sub {
  16.         utf8::downgrade($_[0], 1) or
  17.             Carp::croak("HTTP::Message content must be bytes")
  18.     }
  19.     :
  20.     sub {
  21.     };
  22.  
  23. sub new
  24. {
  25.     my($class, $header, $content) = @_;
  26.     if (defined $header) {
  27.     Carp::croak("Bad header argument") unless ref $header;
  28.         if (ref($header) eq "ARRAY") {
  29.         $header = HTTP::Headers->new(@$header);
  30.     }
  31.     else {
  32.         $header = $header->clone;
  33.     }
  34.     }
  35.     else {
  36.     $header = HTTP::Headers->new;
  37.     }
  38.     if (defined $content) {
  39.         _utf8_downgrade($content);
  40.     }
  41.     else {
  42.         $content = '';
  43.     }
  44.  
  45.     bless {
  46.     '_headers' => $header,
  47.     '_content' => $content,
  48.     }, $class;
  49. }
  50.  
  51.  
  52. sub parse
  53. {
  54.     my($class, $str) = @_;
  55.  
  56.     my @hdr;
  57.     while (1) {
  58.     if ($str =~ s/^([^\s:]+)[ \t]*: ?(.*)\n?//) {
  59.         push(@hdr, $1, $2);
  60.         $hdr[-1] =~ s/\r\z//;
  61.     }
  62.     elsif (@hdr && $str =~ s/^([ \t].*)\n?//) {
  63.         $hdr[-1] .= "\n$1";
  64.         $hdr[-1] =~ s/\r\z//;
  65.     }
  66.     else {
  67.         $str =~ s/^\r?\n//;
  68.         last;
  69.     }
  70.     }
  71.     local $HTTP::Headers::TRANSLATE_UNDERSCORE;
  72.     new($class, \@hdr, $str);
  73. }
  74.  
  75.  
  76. sub clone
  77. {
  78.     my $self  = shift;
  79.     my $clone = HTTP::Message->new($self->headers,
  80.                    $self->content);
  81.     $clone->protocol($self->protocol);
  82.     $clone;
  83. }
  84.  
  85.  
  86. sub clear {
  87.     my $self = shift;
  88.     $self->{_headers}->clear;
  89.     $self->content("");
  90.     delete $self->{_parts};
  91.     return;
  92. }
  93.  
  94.  
  95. sub protocol {
  96.     shift->_elem('_protocol',  @_);
  97. }
  98.  
  99. sub headers {
  100.     my $self = shift;
  101.  
  102.     # recalculation of _content might change headers, so we
  103.     # need to force it now
  104.     $self->_content unless exists $self->{_content};
  105.  
  106.     $self->{_headers};
  107. }
  108.  
  109. sub headers_as_string {
  110.     shift->headers->as_string(@_);
  111. }
  112.  
  113.  
  114. sub content  {
  115.  
  116.     my $self = $_[0];
  117.     if (defined(wantarray)) {
  118.     $self->_content unless exists $self->{_content};
  119.     my $old = $self->{_content};
  120.     $old = $$old if ref($old) eq "SCALAR";
  121.     &_set_content if @_ > 1;
  122.     return $old;
  123.     }
  124.  
  125.     if (@_ > 1) {
  126.     &_set_content;
  127.     }
  128.     else {
  129.     Carp::carp("Useless content call in void context") if $^W;
  130.     }
  131. }
  132.  
  133.  
  134. sub _set_content {
  135.     my $self = $_[0];
  136.     _utf8_downgrade($_[1]);
  137.     if (!ref($_[1]) && ref($self->{_content}) eq "SCALAR") {
  138.     ${$self->{_content}} = $_[1];
  139.     }
  140.     else {
  141.     die "Can't set content to be a scalar reference" if ref($_[1]) eq "SCALAR";
  142.     $self->{_content} = $_[1];
  143.     delete $self->{_content_ref};
  144.     }
  145.     delete $self->{_parts} unless $_[2];
  146. }
  147.  
  148.  
  149. sub add_content
  150. {
  151.     my $self = shift;
  152.     $self->_content unless exists $self->{_content};
  153.     my $chunkref = \$_[0];
  154.     $chunkref = $$chunkref if ref($$chunkref);  # legacy
  155.  
  156.     _utf8_downgrade($$chunkref);
  157.  
  158.     my $ref = ref($self->{_content});
  159.     if (!$ref) {
  160.     $self->{_content} .= $$chunkref;
  161.     }
  162.     elsif ($ref eq "SCALAR") {
  163.     ${$self->{_content}} .= $$chunkref;
  164.     }
  165.     else {
  166.     Carp::croak("Can't append to $ref content");
  167.     }
  168.     delete $self->{_parts};
  169. }
  170.  
  171. sub add_content_utf8 {
  172.     my($self, $buf)  = @_;
  173.     utf8::upgrade($buf);
  174.     utf8::encode($buf);
  175.     $self->add_content($buf);
  176. }
  177.  
  178. sub content_ref
  179. {
  180.     my $self = shift;
  181.     $self->_content unless exists $self->{_content};
  182.     delete $self->{_parts};
  183.     my $old = \$self->{_content};
  184.     my $old_cref = $self->{_content_ref};
  185.     if (@_) {
  186.     my $new = shift;
  187.     Carp::croak("Setting content_ref to a non-ref") unless ref($new);
  188.     delete $self->{_content};  # avoid modifying $$old
  189.     $self->{_content} = $new;
  190.     $self->{_content_ref}++;
  191.     }
  192.     $old = $$old if $old_cref;
  193.     return $old;
  194. }
  195.  
  196.  
  197. sub content_charset
  198. {
  199.     my $self = shift;
  200.     if (my $charset = $self->content_type_charset) {
  201.     return $charset;
  202.     }
  203.  
  204.     # time to start guessing
  205.     my $cref = $self->decoded_content(ref => 1, charset => "none");
  206.  
  207.     # Unicode BOM
  208.     local $_;
  209.     for ($$cref) {
  210.     return "UTF-8"     if /^\xEF\xBB\xBF/;
  211.     return "UTF-32-LE" if /^\xFF\xFE\x00\x00/;
  212.     return "UTF-32-BE" if /^\x00\x00\xFE\xFF/;
  213.     return "UTF-16-LE" if /^\xFF\xFE/;
  214.     return "UTF-16-BE" if /^\xFE\xFF/;
  215.     }
  216.  
  217.     if ($self->content_is_xml) {
  218.     # http://www.w3.org/TR/2006/REC-xml-20060816/#sec-guessing
  219.     # XML entity not accompanied by external encoding information and not
  220.     # in UTF-8 or UTF-16 encoding must begin with an XML encoding declaration,
  221.     # in which the first characters must be '<?xml'
  222.     for ($$cref) {
  223.         return "UTF-32-BE" if /^\x00\x00\x00</;
  224.         return "UTF-32-LE" if /^<\x00\x00\x00/;
  225.         return "UTF-16-BE" if /^(?:\x00\s)*\x00</;
  226.         return "UTF-16-LE" if /^(?:\s\x00)*<\x00/;
  227.         if (/^\s*(<\?xml[^\x00]*?\?>)/) {
  228.         if ($1 =~ /\sencoding\s*=\s*(["'])(.*?)\1/) {
  229.             my $enc = $2;
  230.             $enc =~ s/^\s+//; $enc =~ s/\s+\z//;
  231.             return $enc if $enc;
  232.         }
  233.         }
  234.     }
  235.     return "UTF-8";
  236.     }
  237.     elsif ($self->content_is_html) {
  238.     # look for <META charset="..."> or <META content="...">
  239.     # http://dev.w3.org/html5/spec/Overview.html#determining-the-character-encoding
  240.     my $charset;
  241.     require HTML::Parser;
  242.     my $p = HTML::Parser->new(
  243.         start_h => [sub {
  244.         my($tag, $attr, $self) = @_;
  245.         $charset = $attr->{charset};
  246.         unless ($charset) {
  247.             # look at $attr->{content} ...
  248.             if (my $c = $attr->{content}) {
  249.             require HTTP::Headers::Util;
  250.             my @v = HTTP::Headers::Util::split_header_words($c);
  251.             my($ct, undef, %ct_param) = @{$v[0]};
  252.             $charset = $ct_param{charset};
  253.             }
  254.             return unless $charset;
  255.         }
  256.         if ($charset =~ /^utf-?16/i) {
  257.             # converted document, assume UTF-8
  258.             $charset = "UTF-8";
  259.         }
  260.         $self->eof;
  261.         }, "tagname, attr, self"],
  262.         report_tags => [qw(meta)],
  263.         utf8_mode => 1,
  264.     );
  265.     $p->parse($$cref);
  266.     return $charset if $charset;
  267.     }
  268.     if ($self->content_type =~ /^text\//) {
  269.     for ($$cref) {
  270.         if (length) {
  271.         return "US-ASCII" unless /[\x80-\xFF]/;
  272.         require Encode;
  273.         eval {
  274.             Encode::decode_utf8($_, Encode::FB_CROAK());
  275.         };
  276.         return "UTF-8" unless $@;
  277.         return "ISO-8859-1";
  278.         }
  279.     }
  280.     }
  281.  
  282.     return undef;
  283. }
  284.  
  285.  
  286. sub decoded_content
  287. {
  288.     my($self, %opt) = @_;
  289.     my $content_ref;
  290.     my $content_ref_iscopy;
  291.  
  292.     eval {
  293.     $content_ref = $self->content_ref;
  294.     die "Can't decode ref content" if ref($content_ref) ne "SCALAR";
  295.  
  296.     if (my $h = $self->header("Content-Encoding")) {
  297.         $h =~ s/^\s+//;
  298.         $h =~ s/\s+$//;
  299.         for my $ce (reverse split(/\s*,\s*/, lc($h))) {
  300.         next unless $ce;
  301.         next if $ce eq "identity";
  302.         if ($ce eq "gzip" || $ce eq "x-gzip") {
  303.             require Compress::Zlib;
  304.             unless ($content_ref_iscopy) {
  305.             # memGunzip is documented to destroy its buffer argument
  306.             my $copy = $$content_ref;
  307.             $content_ref = \$copy;
  308.             $content_ref_iscopy++;
  309.             }
  310.             $content_ref = \Compress::Zlib::memGunzip($$content_ref);
  311.             die "Can't gunzip content" unless defined $$content_ref;
  312.         }
  313.         elsif ($ce eq "x-bzip2") {
  314.             require Compress::Bzip2;
  315.             my $i = Compress::Bzip2::bzinflateInit() or
  316.             die "Can't init bzip2 inflater: $Compress::Bzip2::bzerrno";
  317.             unless ($content_ref_iscopy) {
  318.             # the $i->bzinflate method is documented to destroy its
  319.             # buffer argument
  320.             my $copy = $$content_ref;
  321.             $content_ref = \$copy;
  322.             $content_ref_iscopy++;
  323.             }
  324.             # TODO: operate on the ref when rt#48124 is fixed
  325.             my ($out, $status) = $i->bzinflate($$content_ref);
  326.             my $bzerr = "";
  327.             # TODO: drop $out definedness part when rt#48124 is fixed
  328.             if (!defined($out) &&
  329.             $status != Compress::Bzip2::BZ_STREAM_END()) {
  330.             if ($status == Compress::Bzip2::BZ_OK()) {
  331.                 $self->push_header("Client-Warning" =>
  332.                    "Content might be truncated; incomplete bzip2 stream");
  333.             }
  334.             else {
  335.                 # something went bad, can't trust $out any more
  336.                 $out = undef;
  337.                 # $bzerrno has more info than $i->bzerror or $status
  338.                 $bzerr = ": $Compress::Bzip2::bzerrno";
  339.             }
  340.             }
  341.             die "Can't bunzip content$bzerr" unless defined $out;
  342.             $content_ref = \$out;
  343.             $content_ref_iscopy++;
  344.         }
  345.         elsif ($ce eq "deflate") {
  346.             require Compress::Zlib;
  347.             my $out = Compress::Zlib::uncompress($$content_ref);
  348.             unless (defined $out) {
  349.             # "Content-Encoding: deflate" is supposed to mean the "zlib"
  350.                         # format of RFC 1950, but Microsoft got that wrong, so some
  351.                         # servers sends the raw compressed "deflate" data.  This
  352.                         # tries to inflate this format.
  353.             unless ($content_ref_iscopy) {
  354.                 # the $i->inflate method is documented to destroy its
  355.                 # buffer argument
  356.                 my $copy = $$content_ref;
  357.                 $content_ref = \$copy;
  358.                 $content_ref_iscopy++;
  359.             }
  360.  
  361.             my($i, $status) = Compress::Zlib::inflateInit(
  362.                 WindowBits => -Compress::Zlib::MAX_WBITS(),
  363.                         );
  364.             my $OK = Compress::Zlib::Z_OK();
  365.             die "Can't init inflate object" unless $i && $status == $OK;
  366.             ($out, $status) = $i->inflate($content_ref);
  367.             if ($status != Compress::Zlib::Z_STREAM_END()) {
  368.                 if ($status == $OK) {
  369.                 $self->push_header("Client-Warning" =>
  370.                     "Content might be truncated; incomplete deflate stream");
  371.                 }
  372.                 else {
  373.                 # something went bad, can't trust $out any more
  374.                 $out = undef;
  375.                 }
  376.             }
  377.             }
  378.             die "Can't inflate content" unless defined $out;
  379.             $content_ref = \$out;
  380.             $content_ref_iscopy++;
  381.         }
  382.         elsif ($ce eq "compress" || $ce eq "x-compress") {
  383.             die "Can't uncompress content";
  384.         }
  385.         elsif ($ce eq "base64") {  # not really C-T-E, but should be harmless
  386.             require MIME::Base64;
  387.             $content_ref = \MIME::Base64::decode($$content_ref);
  388.             $content_ref_iscopy++;
  389.         }
  390.         elsif ($ce eq "quoted-printable") { # not really C-T-E, but should be harmless
  391.             require MIME::QuotedPrint;
  392.             $content_ref = \MIME::QuotedPrint::decode($$content_ref);
  393.             $content_ref_iscopy++;
  394.         }
  395.         else {
  396.             die "Don't know how to decode Content-Encoding '$ce'";
  397.         }
  398.         }
  399.     }
  400.  
  401.     if ($self->content_is_text || $self->content_is_xml) {
  402.         my $charset = lc(
  403.             $opt{charset} ||
  404.         $self->content_type_charset ||
  405.         $opt{default_charset} ||
  406.         $self->content_charset ||
  407.         "ISO-8859-1"
  408.         );
  409.         unless ($charset =~ /^(?:none|us-ascii|iso-8859-1)\z/) {
  410.         require Encode;
  411.         if (do{my $v = $Encode::VERSION; $v =~ s/_//g; $v} < 2.0901 &&
  412.             !$content_ref_iscopy)
  413.         {
  414.             # LEAVE_SRC did not work before Encode-2.0901
  415.             my $copy = $$content_ref;
  416.             $content_ref = \$copy;
  417.             $content_ref_iscopy++;
  418.         }
  419.         $content_ref = \Encode::decode($charset, $$content_ref,
  420.              ($opt{charset_strict} ? Encode::FB_CROAK() : 0) | Encode::LEAVE_SRC());
  421.         die "Encode::decode() returned undef improperly" unless defined $$content_ref;
  422.         }
  423.     }
  424.     };
  425.     if ($@) {
  426.     Carp::croak($@) if $opt{raise_error};
  427.     return undef;
  428.     }
  429.  
  430.     return $opt{ref} ? $content_ref : $$content_ref;
  431. }
  432.  
  433.  
  434. sub decodable
  435. {
  436.     # should match the Content-Encoding values that decoded_content can deal with
  437.     my $self = shift;
  438.     my @enc;
  439.     # XXX preferably we should determine if the modules are available without loading
  440.     # them here
  441.     eval {
  442.         require Compress::Zlib;
  443.         push(@enc, "gzip", "x-gzip", "deflate");
  444.     };
  445.     eval {
  446.         require Compress::Bzip2;
  447.         push(@enc, "x-bzip2");
  448.     };
  449.     # we don't care about announcing the 'identity', 'base64' and
  450.     # 'quoted-printable' stuff
  451.     return wantarray ? @enc : join(", ", @enc);
  452. }
  453.  
  454.  
  455. sub decode
  456. {
  457.     my $self = shift;
  458.     return 1 unless $self->header("Content-Encoding");
  459.     if (defined(my $content = $self->decoded_content(charset => "none"))) {
  460.     $self->remove_header("Content-Encoding", "Content-Length", "Content-MD5");
  461.     $self->content($content);
  462.     return 1;
  463.     }
  464.     return 0;
  465. }
  466.  
  467.  
  468. sub encode
  469. {
  470.     my($self, @enc) = @_;
  471.  
  472.     Carp::croak("Can't encode multipart/* messages") if $self->content_type =~ m,^multipart/,;
  473.     Carp::croak("Can't encode message/* messages") if $self->content_type =~ m,^message/,;
  474.  
  475.     return 1 unless @enc;  # nothing to do
  476.  
  477.     my $content = $self->content;
  478.     for my $encoding (@enc) {
  479.     if ($encoding eq "identity") {
  480.         # nothing to do
  481.     }
  482.     elsif ($encoding eq "base64") {
  483.         require MIME::Base64;
  484.         $content = MIME::Base64::encode($content);
  485.     }
  486.     elsif ($encoding eq "gzip" || $encoding eq "x-gzip") {
  487.         require Compress::Zlib;
  488.         $content = Compress::Zlib::memGzip($content);
  489.     }
  490.     elsif ($encoding eq "deflate") {
  491.         require Compress::Zlib;
  492.         $content = Compress::Zlib::compress($content);
  493.     }
  494.     elsif ($encoding eq "x-bzip2") {
  495.         require Compress::Bzip2;
  496.         my $d = Compress::Bzip2::bzdeflateInit() or
  497.         die "Can't init bzip2 deflater: $Compress::Bzip2::bzerrno";
  498.         ($content, my $status) = $d->bzdeflate($content);
  499.         die "Can't bzip content: $Compress::Bzip2::bzerrno"
  500.         unless $status == Compress::Bzip2::BZ_OK();
  501.         (my $rest, $status) = $d->bzclose;
  502.         die "Can't bzip content: $Compress::Bzip2::bzerrno"
  503.         unless $status == Compress::Bzip2::BZ_OK();
  504.         $content .= $rest if defined $rest;
  505.     }
  506.     elsif ($encoding eq "rot13") {  # for the fun of it
  507.         $content =~ tr/A-Za-z/N-ZA-Mn-za-m/;
  508.     }
  509.     else {
  510.         return 0;
  511.     }
  512.     }
  513.     my $h = $self->header("Content-Encoding");
  514.     unshift(@enc, $h) if $h;
  515.     $self->header("Content-Encoding", join(", ", @enc));
  516.     $self->remove_header("Content-Length", "Content-MD5");
  517.     $self->content($content);
  518.     return 1;
  519. }
  520.  
  521.  
  522. sub as_string
  523. {
  524.     my($self, $eol) = @_;
  525.     $eol = "\n" unless defined $eol;
  526.  
  527.     # The calculation of content might update the headers
  528.     # so we need to do that first.
  529.     my $content = $self->content;
  530.  
  531.     return join("", $self->{'_headers'}->as_string($eol),
  532.             $eol,
  533.             $content,
  534.             (@_ == 1 && length($content) &&
  535.              $content !~ /\n\z/) ? "\n" : "",
  536.         );
  537. }
  538.  
  539.  
  540. sub dump
  541. {
  542.     my($self, %opt) = @_;
  543.     my $content = $self->content;
  544.     my $chopped = 0;
  545.     if (!ref($content)) {
  546.     my $maxlen = $opt{maxlength};
  547.     $maxlen = 512 unless defined($maxlen);
  548.     if ($maxlen && length($content) > $maxlen * 1.1 + 3) {
  549.         $chopped = length($content) - $maxlen;
  550.         $content = substr($content, 0, $maxlen) . "...";
  551.     }
  552.  
  553.     $content =~ s/\\/\\\\/g;
  554.     $content =~ s/\t/\\t/g;
  555.     $content =~ s/\r/\\r/g;
  556.  
  557.     # no need for 3 digits in escape for these
  558.     $content =~ s/([\0-\11\13-\037])(?!\d)/sprintf('\\%o',ord($1))/eg;
  559.  
  560.     $content =~ s/([\0-\11\13-\037\177-\377])/sprintf('\\x%02X',ord($1))/eg;
  561.     $content =~ s/([^\12\040-\176])/sprintf('\\x{%X}',ord($1))/eg;
  562.  
  563.     # remaining whitespace
  564.     $content =~ s/( +)\n/("\\40" x length($1)) . "\n"/eg;
  565.     $content =~ s/(\n+)\n/("\\n" x length($1)) . "\n"/eg;
  566.     $content =~ s/\n\z/\\n/;
  567.  
  568.     my $no_content = "(no content)";
  569.     if ($content eq $no_content) {
  570.         # escape our $no_content marker
  571.         $content =~ s/^(.)/sprintf('\\x%02X',ord($1))/eg;
  572.     }
  573.     elsif ($content eq "") {
  574.         $content = "(no content)";
  575.     }
  576.     }
  577.  
  578.     my @dump;
  579.     push(@dump, $opt{preheader}) if $opt{preheader};
  580.     push(@dump, $self->{_headers}->as_string, $content);
  581.     push(@dump, "(+ $chopped more bytes not shown)") if $chopped;
  582.  
  583.     my $dump = join("\n", @dump, "");
  584.     $dump =~ s/^/$opt{prefix}/gm if $opt{prefix};
  585.  
  586.     print $dump unless defined wantarray;
  587.     return $dump;
  588. }
  589.  
  590.  
  591. sub parts {
  592.     my $self = shift;
  593.     if (defined(wantarray) && (!exists $self->{_parts} || ref($self->{_content}) eq "SCALAR")) {
  594.     $self->_parts;
  595.     }
  596.     my $old = $self->{_parts};
  597.     if (@_) {
  598.     my @parts = map { ref($_) eq 'ARRAY' ? @$_ : $_ } @_;
  599.     my $ct = $self->content_type || "";
  600.     if ($ct =~ m,^message/,) {
  601.         Carp::croak("Only one part allowed for $ct content")
  602.         if @parts > 1;
  603.     }
  604.     elsif ($ct !~ m,^multipart/,) {
  605.         $self->remove_content_headers;
  606.         $self->content_type("multipart/mixed");
  607.     }
  608.     $self->{_parts} = \@parts;
  609.     _stale_content($self);
  610.     }
  611.     return @$old if wantarray;
  612.     return $old->[0];
  613. }
  614.  
  615. sub add_part {
  616.     my $self = shift;
  617.     if (($self->content_type || "") !~ m,^multipart/,) {
  618.     my $p = HTTP::Message->new($self->remove_content_headers,
  619.                    $self->content(""));
  620.     $self->content_type("multipart/mixed");
  621.     $self->{_parts} = [];
  622.         if ($p->headers->header_field_names || $p->content ne "") {
  623.             push(@{$self->{_parts}}, $p);
  624.         }
  625.     }
  626.     elsif (!exists $self->{_parts} || ref($self->{_content}) eq "SCALAR") {
  627.     $self->_parts;
  628.     }
  629.  
  630.     push(@{$self->{_parts}}, @_);
  631.     _stale_content($self);
  632.     return;
  633. }
  634.  
  635. sub _stale_content {
  636.     my $self = shift;
  637.     if (ref($self->{_content}) eq "SCALAR") {
  638.     # must recalculate now
  639.     $self->_content;
  640.     }
  641.     else {
  642.     # just invalidate cache
  643.     delete $self->{_content};
  644.     delete $self->{_content_ref};
  645.     }
  646. }
  647.  
  648.  
  649. # delegate all other method calls the the headers object.
  650. sub AUTOLOAD
  651. {
  652.     my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::')+2);
  653.  
  654.     # We create the function here so that it will not need to be
  655.     # autoloaded the next time.
  656.     no strict 'refs';
  657.     *$method = sub { shift->headers->$method(@_) };
  658.     goto &$method;
  659. }
  660.  
  661.  
  662. sub DESTROY {}  # avoid AUTOLOADing it
  663.  
  664.  
  665. # Private method to access members in %$self
  666. sub _elem
  667. {
  668.     my $self = shift;
  669.     my $elem = shift;
  670.     my $old = $self->{$elem};
  671.     $self->{$elem} = $_[0] if @_;
  672.     return $old;
  673. }
  674.  
  675.  
  676. # Create private _parts attribute from current _content
  677. sub _parts {
  678.     my $self = shift;
  679.     my $ct = $self->content_type;
  680.     if ($ct =~ m,^multipart/,) {
  681.     require HTTP::Headers::Util;
  682.     my @h = HTTP::Headers::Util::split_header_words($self->header("Content-Type"));
  683.     die "Assert" unless @h;
  684.     my %h = @{$h[0]};
  685.     if (defined(my $b = $h{boundary})) {
  686.         my $str = $self->content;
  687.         $str =~ s/\r?\n--\Q$b\E--\r?\n.*//s;
  688.         if ($str =~ s/(^|.*?\r?\n)--\Q$b\E\r?\n//s) {
  689.         $self->{_parts} = [map HTTP::Message->parse($_),
  690.                    split(/\r?\n--\Q$b\E\r?\n/, $str)]
  691.         }
  692.     }
  693.     }
  694.     elsif ($ct eq "message/http") {
  695.     require HTTP::Request;
  696.     require HTTP::Response;
  697.     my $content = $self->content;
  698.     my $class = ($content =~ m,^(HTTP/.*)\n,) ?
  699.         "HTTP::Response" : "HTTP::Request";
  700.     $self->{_parts} = [$class->parse($content)];
  701.     }
  702.     elsif ($ct =~ m,^message/,) {
  703.     $self->{_parts} = [ HTTP::Message->parse($self->content) ];
  704.     }
  705.  
  706.     $self->{_parts} ||= [];
  707. }
  708.  
  709.  
  710. # Create private _content attribute from current _parts
  711. sub _content {
  712.     my $self = shift;
  713.     my $ct = $self->{_headers}->header("Content-Type") || "multipart/mixed";
  714.     if ($ct =~ m,^\s*message/,i) {
  715.     _set_content($self, $self->{_parts}[0]->as_string($CRLF), 1);
  716.     return;
  717.     }
  718.  
  719.     require HTTP::Headers::Util;
  720.     my @v = HTTP::Headers::Util::split_header_words($ct);
  721.     Carp::carp("Multiple Content-Type headers") if @v > 1;
  722.     @v = @{$v[0]};
  723.  
  724.     my $boundary;
  725.     my $boundary_index;
  726.     for (my @tmp = @v; @tmp;) {
  727.     my($k, $v) = splice(@tmp, 0, 2);
  728.     if ($k eq "boundary") {
  729.         $boundary = $v;
  730.         $boundary_index = @v - @tmp - 1;
  731.         last;
  732.     }
  733.     }
  734.  
  735.     my @parts = map $_->as_string($CRLF), @{$self->{_parts}};
  736.  
  737.     my $bno = 0;
  738.     $boundary = _boundary() unless defined $boundary;
  739.  CHECK_BOUNDARY:
  740.     {
  741.     for (@parts) {
  742.         if (index($_, $boundary) >= 0) {
  743.         # must have a better boundary
  744.         $boundary = _boundary(++$bno);
  745.         redo CHECK_BOUNDARY;
  746.         }
  747.     }
  748.     }
  749.  
  750.     if ($boundary_index) {
  751.     $v[$boundary_index] = $boundary;
  752.     }
  753.     else {
  754.     push(@v, boundary => $boundary);
  755.     }
  756.  
  757.     $ct = HTTP::Headers::Util::join_header_words(@v);
  758.     $self->{_headers}->header("Content-Type", $ct);
  759.  
  760.     _set_content($self, "--$boundary$CRLF" .
  761.                     join("$CRLF--$boundary$CRLF", @parts) .
  762.             "$CRLF--$boundary--$CRLF",
  763.                         1);
  764. }
  765.  
  766.  
  767. sub _boundary
  768. {
  769.     my $size = shift || return "xYzZY";
  770.     require MIME::Base64;
  771.     my $b = MIME::Base64::encode(join("", map chr(rand(256)), 1..$size*3), "");
  772.     $b =~ s/[\W]/X/g;  # ensure alnum only
  773.     $b;
  774. }
  775.  
  776.  
  777. 1;
  778.  
  779.  
  780. __END__
  781.  
  782. =head1 NAME
  783.  
  784. HTTP::Message - HTTP style message (base class)
  785.  
  786. =head1 SYNOPSIS
  787.  
  788.  use base 'HTTP::Message';
  789.  
  790. =head1 DESCRIPTION
  791.  
  792. An C<HTTP::Message> object contains some headers and a content body.
  793. The following methods are available:
  794.  
  795. =over 4
  796.  
  797. =item $mess = HTTP::Message->new
  798.  
  799. =item $mess = HTTP::Message->new( $headers )
  800.  
  801. =item $mess = HTTP::Message->new( $headers, $content )
  802.  
  803. This constructs a new message object.  Normally you would want
  804. construct C<HTTP::Request> or C<HTTP::Response> objects instead.
  805.  
  806. The optional $header argument should be a reference to an
  807. C<HTTP::Headers> object or a plain array reference of key/value pairs.
  808. If an C<HTTP::Headers> object is provided then a copy of it will be
  809. embedded into the constructed message, i.e. it will not be owned and
  810. can be modified afterwards without affecting the message.
  811.  
  812. The optional $content argument should be a string of bytes.
  813.  
  814. =item $mess = HTTP::Message->parse( $str )
  815.  
  816. This constructs a new message object by parsing the given string.
  817.  
  818. =item $mess->headers
  819.  
  820. Returns the embedded C<HTTP::Headers> object.
  821.  
  822. =item $mess->headers_as_string
  823.  
  824. =item $mess->headers_as_string( $eol )
  825.  
  826. Call the as_string() method for the headers in the
  827. message.  This will be the same as
  828.  
  829.     $mess->headers->as_string
  830.  
  831. but it will make your program a whole character shorter :-)
  832.  
  833. =item $mess->content
  834.  
  835. =item $mess->content( $bytes )
  836.  
  837. The content() method sets the raw content if an argument is given.  If no
  838. argument is given the content is not touched.  In either case the
  839. original raw content is returned.
  840.  
  841. Note that the content should be a string of bytes.  Strings in perl
  842. can contain characters outside the range of a byte.  The C<Encode>
  843. module can be used to turn such strings into a string of bytes.
  844.  
  845. =item $mess->add_content( $bytes )
  846.  
  847. The add_content() methods appends more data bytes to the end of the
  848. current content buffer.
  849.  
  850. =item $mess->add_content_utf8( $string )
  851.  
  852. The add_content_utf8() method appends the UTF-8 bytes representing the
  853. string to the end of the current content buffer.
  854.  
  855. =item $mess->content_ref
  856.  
  857. =item $mess->content_ref( \$bytes )
  858.  
  859. The content_ref() method will return a reference to content buffer string.
  860. It can be more efficient to access the content this way if the content
  861. is huge, and it can even be used for direct manipulation of the content,
  862. for instance:
  863.  
  864.   ${$res->content_ref} =~ s/\bfoo\b/bar/g;
  865.  
  866. This example would modify the content buffer in-place.
  867.  
  868. If an argument is passed it will setup the content to reference some
  869. external source.  The content() and add_content() methods
  870. will automatically dereference scalar references passed this way.  For
  871. other references content() will return the reference itself and
  872. add_content() will refuse to do anything.
  873.  
  874. =item $mess->content_charset
  875.  
  876. This returns the charset used by the content in the message.  The
  877. charset is either found as the charset attribute of the
  878. C<Content-Type> header or by guessing.
  879.  
  880. See L<http://www.w3.org/TR/REC-html40/charset.html#spec-char-encoding>
  881. for details about how charset is determined.
  882.  
  883. =item $mess->decoded_content( %options )
  884.  
  885. Returns the content with any C<Content-Encoding> undone and the raw
  886. content encoded to perl's Unicode strings.  If the C<Content-Encoding>
  887. or C<charset> of the message is unknown this method will fail by
  888. returning C<undef>.
  889.  
  890. The following options can be specified.
  891.  
  892. =over
  893.  
  894. =item C<charset>
  895.  
  896. This override the charset parameter for text content.  The value
  897. C<none> can used to suppress decoding of the charset.
  898.  
  899. =item C<default_charset>
  900.  
  901. This override the default charset guessed by content_charset() or
  902. if that fails "ISO-8859-1".
  903.  
  904. =item C<charset_strict>
  905.  
  906. Abort decoding if malformed characters is found in the content.  By
  907. default you get the substitution character ("\x{FFFD}") in place of
  908. malformed characters.
  909.  
  910. =item C<raise_error>
  911.  
  912. If TRUE then raise an exception if not able to decode content.  Reason
  913. might be that the specified C<Content-Encoding> or C<charset> is not
  914. supported.  If this option is FALSE, then decoded_content() will return
  915. C<undef> on errors, but will still set $@.
  916.  
  917. =item C<ref>
  918.  
  919. If TRUE then a reference to decoded content is returned.  This might
  920. be more efficient in cases where the decoded content is identical to
  921. the raw content as no data copying is required in this case.
  922.  
  923. =back
  924.  
  925. =item $mess->decodable
  926.  
  927. =item HTTP::Message::decodable()
  928.  
  929. This returns the encoding identifiers that decoded_content() can
  930. process.  In scalar context returns a comma separated string of
  931. identifiers.
  932.  
  933. This value is suitable for initializing the C<Accept-Encoding> request
  934. header field.
  935.  
  936. =item $mess->decode
  937.  
  938. This method tries to replace the content of the message with the
  939. decoded version and removes the C<Content-Encoding> header.  Returns
  940. TRUE if successful and FALSE if not.
  941.  
  942. If the message does not have a C<Content-Encoding> header this method
  943. does nothing and returns TRUE.
  944.  
  945. Note that the content of the message is still bytes after this method
  946. has been called and you still need to call decoded_content() if you
  947. want to process its content as a string.
  948.  
  949. =item $mess->encode( $encoding, ... )
  950.  
  951. Apply the given encodings to the content of the message.  Returns TRUE
  952. if successful. The "identity" (non-)encoding is always supported; other
  953. currently supported encodings, subject to availability of required
  954. additional modules, are "gzip", "deflate", "x-bzip2" and "base64".
  955.  
  956. A successful call to this function will set the C<Content-Encoding>
  957. header.
  958.  
  959. Note that C<multipart/*> or C<message/*> messages can't be encoded and
  960. this method will croak if you try.
  961.  
  962. =item $mess->parts
  963.  
  964. =item $mess->parts( @parts )
  965.  
  966. =item $mess->parts( \@parts )
  967.  
  968. Messages can be composite, i.e. contain other messages.  The composite
  969. messages have a content type of C<multipart/*> or C<message/*>.  This
  970. method give access to the contained messages.
  971.  
  972. The argumentless form will return a list of C<HTTP::Message> objects.
  973. If the content type of $msg is not C<multipart/*> or C<message/*> then
  974. this will return the empty list.  In scalar context only the first
  975. object is returned.  The returned message parts should be regarded as
  976. read-only (future versions of this library might make it possible
  977. to modify the parent by modifying the parts).
  978.  
  979. If the content type of $msg is C<message/*> then there will only be
  980. one part returned.
  981.  
  982. If the content type is C<message/http>, then the return value will be
  983. either an C<HTTP::Request> or an C<HTTP::Response> object.
  984.  
  985. If an @parts argument is given, then the content of the message will be
  986. modified. The array reference form is provided so that an empty list
  987. can be provided.  The @parts array should contain C<HTTP::Message>
  988. objects.  The @parts objects are owned by $mess after this call and
  989. should not be modified or made part of other messages.
  990.  
  991. When updating the message with this method and the old content type of
  992. $mess is not C<multipart/*> or C<message/*>, then the content type is
  993. set to C<multipart/mixed> and all other content headers are cleared.
  994.  
  995. This method will croak if the content type is C<message/*> and more
  996. than one part is provided.
  997.  
  998. =item $mess->add_part( $part )
  999.  
  1000. This will add a part to a message.  The $part argument should be
  1001. another C<HTTP::Message> object.  If the previous content type of
  1002. $mess is not C<multipart/*> then the old content (together with all
  1003. content headers) will be made part #1 and the content type made
  1004. C<multipart/mixed> before the new part is added.  The $part object is
  1005. owned by $mess after this call and should not be modified or made part
  1006. of other messages.
  1007.  
  1008. There is no return value.
  1009.  
  1010. =item $mess->clear
  1011.  
  1012. Will clear the headers and set the content to the empty string.  There
  1013. is no return value
  1014.  
  1015. =item $mess->protocol
  1016.  
  1017. =item $mess->protocol( $proto )
  1018.  
  1019. Sets the HTTP protocol used for the message.  The protocol() is a string
  1020. like C<HTTP/1.0> or C<HTTP/1.1>.
  1021.  
  1022. =item $mess->clone
  1023.  
  1024. Returns a copy of the message object.
  1025.  
  1026. =item $mess->as_string
  1027.  
  1028. =item $mess->as_string( $eol )
  1029.  
  1030. Returns the message formatted as a single string.
  1031.  
  1032. The optional $eol parameter specifies the line ending sequence to use.
  1033. The default is "\n".  If no $eol is given then as_string will ensure
  1034. that the returned string is newline terminated (even when the message
  1035. content is not).  No extra newline is appended if an explicit $eol is
  1036. passed.
  1037.  
  1038. =item $mess->dump( %opt )
  1039.  
  1040. Returns the message formatted as a string.  In void context print the string.
  1041.  
  1042. This differs from C<< $mess->as_string >> in that it escapes the bytes
  1043. of the content so that it's safe to print them and it limits how much
  1044. content to print.  The escapes syntax used is the same as for Perl's
  1045. double quoted strings.  If there is no content the string "(no
  1046. content)" is shown in its place.
  1047.  
  1048. Options to influence the output can be passed as key/value pairs. The
  1049. following options are recognized:
  1050.  
  1051. =over
  1052.  
  1053. =item maxlength => $num
  1054.  
  1055. How much of the content to show.  The default is 512.  Set this to 0
  1056. for unlimited.
  1057.  
  1058. If the content is longer then the string is chopped at the limit and
  1059. the string "...\n(### more bytes not shown)" appended.
  1060.  
  1061. =item prefix => $str
  1062.  
  1063. A string that will be prefixed to each line of the dump.
  1064.  
  1065. =back
  1066.  
  1067. =back
  1068.  
  1069. All methods unknown to C<HTTP::Message> itself are delegated to the
  1070. C<HTTP::Headers> object that is part of every message.  This allows
  1071. convenient access to these methods.  Refer to L<HTTP::Headers> for
  1072. details of these methods:
  1073.  
  1074.     $mess->header( $field => $val )
  1075.     $mess->push_header( $field => $val )
  1076.     $mess->init_header( $field => $val )
  1077.     $mess->remove_header( $field )
  1078.     $mess->remove_content_headers
  1079.     $mess->header_field_names
  1080.     $mess->scan( \&doit )
  1081.  
  1082.     $mess->date
  1083.     $mess->expires
  1084.     $mess->if_modified_since
  1085.     $mess->if_unmodified_since
  1086.     $mess->last_modified
  1087.     $mess->content_type
  1088.     $mess->content_encoding
  1089.     $mess->content_length
  1090.     $mess->content_language
  1091.     $mess->title
  1092.     $mess->user_agent
  1093.     $mess->server
  1094.     $mess->from
  1095.     $mess->referer
  1096.     $mess->www_authenticate
  1097.     $mess->authorization
  1098.     $mess->proxy_authorization
  1099.     $mess->authorization_basic
  1100.     $mess->proxy_authorization_basic
  1101.  
  1102. =head1 COPYRIGHT
  1103.  
  1104. Copyright 1995-2004 Gisle Aas.
  1105.  
  1106. This library is free software; you can redistribute it and/or
  1107. modify it under the same terms as Perl itself.
  1108.  
  1109.